# 示例：recursively_split.py
# 递归文本分割器示例
'''
RecursiveCharacterTextSplitter 的工作原理
递归分割：按优先级尝试不同的分隔符 ，直到块足够小，能够保持段落，句子在一起
分隔符优先级：
    首先尝试用 \n\n 分割段落
    如果还太大，用 \n 分割行
    如果还太大，用空格分割单词
    最后用空字符分割单个字符
'''

# 导入递归字符文本分割器
from langchain_text_splitters import RecursiveCharacterTextSplitter

# 加载示例文档
# 打开并读取知识库文本文件，使用UTF-8编码确保中文正常显示
with open("./llm_langchain_data/knowledge.txt", encoding="utf-8") as f:
    state_of_the_union = f.read()  # 将整个文件内容读入字符串变量

# 创建递归字符文本分割器实例
text_splitter = RecursiveCharacterTextSplitter(
    # chunk_size: 每个文本块的最大字符数
    # 这里设置为100只是为了演示，实际使用时通常设置为500-2000
    chunk_size=100,

    # chunk_overlap: 相邻文本块之间的重叠字符数
    # 重叠可以保持上下文的连贯性，避免在句子中间被切断
    chunk_overlap=20,

    # length_function: 用于计算文本长度的函数
    # 这里使用len函数，按字符数计算长度
    # 如果需要按token数计算，可以使用其他函数
    length_function=len,

    # is_separator_regex: 分隔符是否使用正则表达式
    # 设置为False表示使用普通字符串作为分隔符
    is_separator_regex=False,

    # 注意：RecursiveCharacterTextSplitter默认使用以下分隔符优先级进行分割：
    # 1. "\n\n" (双换行 - 段落分隔)
    # 2. "\n"   (单换行 - 行分隔)
    # 3. " "    (空格 - 单词分隔)
    # 4. ""     (空字符 - 字符分隔)
    # 它会按这个顺序尝试分割，直到满足chunk_size要求
    separators=[
        "\n\n",  # 双换行 - 段落分隔
        "\n",  # 单换行 - 行分隔
        " ",  # 空格 - 单词分隔（英文）
        ".",  # 句号 - 句子分隔
        ",",  # 逗号 - 子句分隔
        "\u200b",  # 零宽空格 - 特殊分隔符
        "\uff0c",  # 全角逗号 - 中文标点
        "\u3001",  # 表意逗号 - 中文顿号
        "\uff0e",  # 全角句号 - 中文句号
        "\u3002",  # 表意句号 - 中文句号
        "",  # 空字符 - 最后 resort，按字符分割
    ],
)

# 使用分割器创建文档对象
# create_documents方法接受文本列表，返回Document对象列表
# 每个Document对象包含page_content(文本内容)和metadata(元数据)
texts = text_splitter.create_documents([state_of_the_union])

# 打印第一个文本块
print("=== 第一个文本块 ===")
print(texts[0])
# texts[0] 是一个Document对象，包含：
# - page_content: 分割后的文本内容
# - metadata: 元数据信息（这里为空）

print("\n" + "=" * 50 + "\n")

# 打印第二个文本块
print("=== 第二个文本块 ===")
print(texts[1])

# 额外信息：显示分割统计
print("\n" + "=" * 50)
print("分割统计信息:")
print(f"原始文本长度: {len(state_of_the_union)} 字符")
print(f"分割后的文本块数量: {len(texts)}")
print(f"平均每个块长度: {sum(len(text.page_content) for text in texts) / len(texts):.1f} 字符")

# 显示前几个文本块的内容预览
print("\n前5个文本块内容预览:")
for i, text in enumerate(texts[:5]):
    print(f"块 {i + 1}: {text.page_content[:50]}...")  # 显示前50个字符
